iT邦幫忙

2022 iThome 鐵人賽

DAY 25
0
Software Development

如何在Unity裡寫出具有一定擴充性的遊戲系列 第 25

Day 25:interface與abstract class

  • 分享至 

  • xImage
  •  

如果有認真看前面文章的程式碼的話,應該會發現我大部分的範例,在實作抽象層都是用interface,但到實際案例時更多出現的是abstract class,但這是為什麼?

再繼續說下去前,我們可以先看看這兩個放在class會是甚麼樣的規則

interface的實作規則

  • interface不能被具現化(instantiated)
  • 不能包含任何實例狀態(instance state)
  • 強制實作interface所擁有的所有成員

abstract class的實作規則

  • 可以包含實例狀態
  • 抽象類別(abstract class)不能被具現化
  • 可以包含抽象方法(abstract methods)與存取子(accessors)
  • 無法使用sealed修飾(當然啊這種類別就是要被繼承還用不能繼承的修飾...)

如果以Microsoft Net. Framework Design Guidelines的建議來說,如果今天是要創造一個具有可重複利用能力的函式庫時(尤其是那些放在NuGet上的),這類函式庫其中一個特性就是在開發編譯時,並没有預設使用這份函式庫的使用者客群,所以要讓使用者擁有更多的修改彈性空間。

實際上來說,以放在NuGet上的Google Cloud API當作例子,這種會塞不少功能的都會是用abstract class去設計,而裡面的資料不是用virtual宣告,來讓使用者選擇要不要使用or延伸做法,就是用static表示此資料是唯一的
不過即使如此,也可以從這個案例中看出裡面的程式都是有很好的處理其中的權限與程式行數,防止其成為God class的可能性

SpeechClient.cs

namespace Google.Cloud.Speech.V1 
{ 
    public abstract class SpeechClient 
    { 
        protected SpeechClient(); 
        public static ServiceMetadata ServiceMetadata { get; } 
        public static IReadOnlyList<string> DefaultScopes { get; } 
        public static string DefaultEndpoint { get; } 
        public virtual Speech.SpeechClient GrpcClient { get; } 
        public virtual OperationsClient LongRunningRecognizeOperationsClient { get; } 
        public static SpeechClient Create(); 
        public static Task<SpeechClient> CreateAsync(CancellationToken cancellationToken = default); 
        public static Task ShutdownDefaultChannelsAsync();

有些很明確就是不想讓使用者擁有太多修改空間的還是會設計成interface,像是C#本身擁有IReadOnlyList案例

IReadOnlyList.cs

using System.Reflection; 
namespace System.Collections.Generic 
{ 
    [DefaultMember("Item")] 
    public interface IReadOnlyList<out T> : IEnumerable<T>, IEnumerable, IReadOnlyCollection<T> 
    { 
        T this[int index] { get; } 
    } 
}

所以實際上的使用還是要去評估此功能未來的擴充性去決定要用abstract還是interface才行,以目前來說,雖然我的目標是將棋類遊戲的功能模組化,但要真的能設計成那樣還需要一般功夫就是

參考資料

依賴注入:原理、實作與設計模式
interface (C# 參考)
abstract (C# 參考)
Abstractions (Abstract Types and Interfaces)
IReadOnlyList 介面
C# IReadOnlyList用法


上一篇
Day 24:Visitor模式(二)
下一篇
Day 26:ScriptableObject簡介
系列文
如何在Unity裡寫出具有一定擴充性的遊戲30
圖片
  直播研討會
圖片
{{ item.channelVendor }} {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言